热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

画质|基本信息_音视频开发之旅(64)部分android手机编码的视频在ios上无法播放

篇首语:本文由编程笔记#小编为大家整理,主要介绍了音视频开发之旅(64)-部分android手机编码的视频在ios上无法播放相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了音视频开发之旅(64) - 部分android手机编码的视频在ios上无法播放相关的知识,希望对你有一定的参考价值。



目录


  1. 问题描述

  2. 问题分析

  3. 问题原因

  4. 问题解决

  5. 资料

  6. 收获


一、问题描述

用小米11 录制视频上传后,在iPhone的Safari浏览器或者应用的H5中无法播放,而android设备上的确实可以正常播放。

同样的操作,在一些其他android的手机上传的视频,在ios端却可以正常播放。


二、问题分析

拿到(能播放和不能播放)两个视频。分析下这两个视频有什么差异。

通过MediaInfo查看两个视频的基本信息

不能播放的视频



"@type": "Video",
"StreamOrder": "1",
"ID": "2",
"Format": "AVC",
"Format_Profile": "High",
"Format_Level": "6",
"Format_Settings_CABAC": "Yes",
"Format_Settings_RefFrames": "1",

能播放的视频



"@type": "Video",
"Format": "AVC",
"Format_Profile": "Main",
"Format_Level": "3.1",
"Format_Settings_CABAC": "Yes",

可以很明显地看到两个视频的Profile和Level不同。

通过ffmpeg把不能播放的视频进行转码,修改profile和level的值,进行本地快速验证。


ffmpeg -i input.mp4 -profile:v main -level 4.2 output.mp4
ffmpeg -i input.mp4 -profile:v high -level 5.1 output.mp4
ffmpeg -i input.mp4 -profile:v high -level 6 output.mp4

发现只有level大于等于6,在ios上就不能播放。


三、问题原因

我们先来看下Profile和Level是什么?


3.1 Profile


H.264有四种画质级别,分别是baseline, extended, main, high:
  1、Baseline Profile:基本画质。支持I/P 帧,只支持无交错(Progressive)和CAVLC;
  2、Extended profile:进阶画质。支持I/P/B/SP/SI 帧,只支持无交错(Progressive)和CAVLC;(用的少)
  3、Main profile:主流画质。提供I/P/B 帧,支持无交错(Progressive)和交错(Interlaced), 也支持CAVLC 和CABAC 的支持;
  4、High profile:高级画质。在main Profile 的基础上增加了8x8内部预测、自定义量化、 无损视频编码和更多的YUV 格式;

H.264 Baseline profile、Extended profile和Main profile都是针对8位样本数据、4:2:0格式(YUV)的视频序列。

在相同配置情况下,High profile(HP)可以比Main profile(MP)降低10%的码率。
根据应用领域的不同,Baseline profile多应用于实时通信领域,Main profile多应用于流媒体领域,High profile则多应用于广电和存储领域。

维基百科上有对应的表:



3.2 level

level是一组特定的约束,表示一个profile所需的编解码性能。指定编解码器可能使用的最大图像分辨率、帧率和比特率。一个符合给定level的解码器必须能够解码为该level和所有低level编码的所有比特流。

在MediaCodecInfo中有定义各种类型的值


综上,我们可以知道Profile和Level是影响着视频编码的质量和效率。有些设备不支持高Profile、level的编码。所以需要综合考虑兼容性和视频质量。

通过查看代码发现,android端的视频编码时,仅对Profile做了阀值限制,Level没有判断处理,就像小米11手机对应解码器信息返回的Level是6,这样编码出来的视频在某些不支持的该level解码的设备上就无法解码播放。


3.3 扩展

另外通过查找资源,发现android在7.0之前的系统,编码时profile只能是Baseline,如果不是,系统会强制地设置为Baseline。猜测也是为了兼容性吧。虽然更高的压缩比带来很好的收益,但是兼容性(普适性)是优先考虑的点。

使用MediaCodec编码时,通常是这样设置的


先配置MediaCodecInfo的profile信息 然后赋给MediaFormat
codec.configure(format,null,null,MediaCodec.CONFIGURE_FLAG_ENCODE);
最后设置给MediaCodec
编码得到的码流都是baseline profile的
这是由于android sdk本身的限制导致的
ACodec.cpp里的对应处理如下:
if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline)
ALOGW("Use baseline profile instead of %d for AVC recording",
h264type.eProfile);
h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;

在Android 7.0之后才移除了这段代码。也就是说要想使用MP要求Android系统版本在7.0及其以上。

四、问题解决方案


4.1 方案一:用户上传后先经过服务端的转码后,再下发给用户

用户上传的视频可能差别很大(封装格式、编码格式、采样率、码率、帧率、分辨率、YUV存储格式等等),有些播放器可能对某些视频支持的不太好。比如:有些设备不支持HEVC的解码、有些解码器不支持MPEG-4的编码格式、有些播放器只支持YUV420P的格式、有些播放器对于帧率很高的视频卡顿、有些播放器不支持播放4K等高清视频 等等
针对上述情况,一种比较通用的做法是。用户上传后先经过服务端的转码后,再下发给其他用户。进而保证视频在各种设备上的兼容性。


4.2 方案二、编码时的profie和level设置上线阀值

profile 最大值设置为 MediaCodecInfo.CodecProfileLevel.AVCProfileHigh
Level 最大值设置为 MediaCodecInfo.CodecProfileLevel.AVCLevel52
当从解码器中遍历的MediaCodecInfo.CodecProfileLevel的profie和level上述阀值时,用上述最大值。进而保证在各种设备的兼容性。

方案1是更加通用的解决方案,方案2则是脚痛医脚的方案。


五、 资料


  1. H.264 and H.265 (HEVC)(https://help.shopmoment.com/article/135-video-formats-for-ios)

  2. ffmpeg 常用命令(https://www.cnblogs.com/frost-yen/p/5848781.html)

  3. H264编码profile & level控制(https://www.cnblogs.com/tinywan/p/6402007.html)

  4. Using ffprobe to get info from a file in a nice JSON format(https://gist.github.com/nrk/2286511)

  5. Android MediaCodec参数笔记(https://blog.csdn.net/matrix_laboratory/article/details/80929845)

  6. Android MediaCodec h264编码无法设为high profile(https://www.codeleading.com/article/78273619345/)


六、收获

通过本篇的学习


  1. 分析解决部分android设备上编码的视频,ios不能播放的问题

  2. 进一步熟悉Profile、Level的意义

感谢你的阅读

欢迎关注公众号“音视频开发之旅”,一起学习成长。

欢迎交流


推荐阅读
  • 本文介绍了iOS开发中检测和解决内存泄漏的方法,包括静态分析、使用instruments检查内存泄漏以及代码测试等。同时还介绍了最能挣钱的行业,包括互联网行业、娱乐行业、教育行业、智能行业和老年服务行业,并提供了选行业的技巧。 ... [详细]
  • 使用圣杯布局模式实现网站首页的内容布局
    本文介绍了使用圣杯布局模式实现网站首页的内容布局的方法,包括HTML部分代码和实例。同时还提供了公司新闻、最新产品、关于我们、联系我们等页面的布局示例。商品展示区包括了车里子和农家生态土鸡蛋等产品的价格信息。 ... [详细]
  • Android NDK开发的一点尝试
    写在前面笔者是一个“原始”的C++开发者,对Java编程虽说不上抵触但也没有C++那么顺手。而且,作为一个游戏引擎,不管是在什么地方,效率总是第一位的,尤其是在移动平台这样资源吃紧 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了如何清除Eclipse中SVN用户的设置。首先需要查看使用的SVN接口,然后根据接口类型找到相应的目录并删除相关文件。最后使用SVN更新或提交来应用更改。 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • 本文讨论了如何使用GStreamer来删除H264格式视频文件中的中间部分,而不需要进行重编码。作者提出了使用gst_element_seek(...)函数来实现这个目标的思路,并提到遇到了一个解决不了的BUG。文章还列举了8个解决方案,希望能够得到更好的思路。 ... [详细]
  • 苹果手机home键设置1.我们点击打开iPhone手机桌面上的设置图标。2.点击打开页面中的通用选项。 ... [详细]
  • Summarize function is doing alignment without timezone ?
    Hi.Imtryingtogetsummarizefrom00:00otfirstdayofthismonthametric, ... [详细]
  • 大坑|左上角_pycharm连接服务器同步写代码(图文详细过程)
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了pycharm连接服务器同步写代码(图文详细过程)相关的知识,希望对你有一定的参考价值。pycharm连接服务 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了markdown[软件代理设置]相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 我收到这个错误.我怎么能在我的情况下解决这个问题?Bitmapcannotberesolvedtoatype发生错误的行publicvoidonPageStart ... [详细]
  • 项目需要实现弹幕,网上参考了各种方法,最后觉得transform+transition实现的效果在移动设备上性能最好,在iphone6和红米4上测试,看不到 ... [详细]
  • charles3.11.1抓https包
    结论先行:用的是安卓测试机,没加固之前的生产环境的安装包,可以抓到https请求加固之后的包【也就是要上应用市场的包】,抓不到https请求电脑上的操作:1.安装证书【电脑上安装了 ... [详细]
author-avatar
zwjy2018
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有